setting up a headless raspbian boot image

2020-12-12 ยท 3 min read

    Objective #

    1. Custom SD card boot image for Raspberry Pi Zero W.
    2. RPi should boot headless, connect to configured WiFi, run ssh.

    Better Alternative? #

    I only discovered this after successfully generating my own image, but it seems more convenient: (https://github.com/kenfallon/fix-ssh-on-pi, http://www.lpenz.org/articles/ansiblerpi/index.html). It just mounts a stock Raspbian image and directly modifies the wpa_supplicant.conf and other configuration, instead of building a fresh image from scratch, which takes like 45 minutes...

    EDIT: It looks like rpi-imager has basic image customization available? #

    TODO #

    • enable kernel I2C, SPI, and PWM controllers in /boot/config.txt

    Installation #

    (Windows, macOS) Install Docker Desktop #

    See: https://www.docker.com/products/docker-desktop

    Clone pi-gen: #

    $ git clone --depth=1 git@github.com:RPi-Distro/pi-gen.git
    

    Add pi-gen/config #

    IMG_NAME=raspbian_headless
    LOCALE_DEFAULT=en_US.UTF-8
    TARGET_HOSTNAME=<..>
    TIMEZONE_DEFAULT=America/Los_Angeles
    FIRST_USER_NAME=phlip9
    FIRST_USER_PASS=<..>
    DISABLE_FIRST_BOOT_USER_RENAME=1
    WPA_ESSID="<..>"
    WPA_PASSWORD="<..>"
    WPA_COUNTRY=US
    ENABLE_SSH=1
    PUBKEY_ONLY_SSH=1
    PUBKEY_SSH_FIRST_USER="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGrOw2yrUxOYB9ItWrZW4e/AmatL5GH58jTnI/HNoXZz philiphayes9@gmail.com"
    STAGE_LIST="stage0 stage1 stage2"
    

    This config sets up all the locale shit and all, but most importantly, enables wifi on boot and pubkey-only ssh, so we can ssh into the running board without needing to hookup a keyboard / monitor.

    NOTE: The Raspberry Pi Zero W DOES NOT support 5GHz wifi.

    (Linux/x86_64) Install qemu-user-static #

    This lets us run arm binaries on an x86_64 machine via qemu.

    $ sudo apt install qemu-user-static
    

    Context:

    Linux is able execute binaries from other architectures, meaning that it should be possible to make use of pi-gen on an x86_64 system, even though it will be running ARM binaries. This requires support from the binfmt_misc kernel module.

    If this is not set up correctly, you will see something like this error in the next step:

    W: Failure trying to run: chroot "/pi-gen/work/test/stage0/rootfs" /bin/true
    and/or
    chroot: failed to run command '/bin/true': Exec format error
    

    Build the image #

    $ ./build-docker.sh
    

    This should spit out our fresh image in ./deploy/:

    ~/dev/pi-gen$ ls -lh deploy/
    total 528M
    -rw-r--r-- 1 phlip9 phlip9  74K Nov 26 15:56 2022-11-26-raspbian_headless-lite.info
    -rw-r--r-- 1 phlip9 phlip9 6.2K Nov 26 15:58 build.log
    -rw-r--r-- 1 phlip9 phlip9 528M Nov 26 15:57 image_2022-11-26-raspbian_headless-lite.zip
    drwxr-xr-x 2 phlip9 phlip9 4.0K Nov 26 15:58 raspbian_headless-lite
    

    If the build hangs/fails for some inscrutable reason (happened the first time), just ^CTRL-C and try again with:

    $ CONTINUE=1 ./build-docker.sh
    

    (WSL) I tried their suggestion of using apt-cache to improve rebuild times, but that didn't work :'(

    Mount SD card #

    Download Raspberry Pi Imager #

    https://www.raspberrypi.org/software/

    Open Raspberry Pi Imager #

    Select the "deploy/*.zip" file as the image to write and then image the mounted SD card. #

    Unmount the SD card, put it into the Pi, plug in the Pi, wait ~2 min to boot, and test: #

    $ ssh raspberrypi.local
    
    phlip9@raspberrypi:~ $ exit